package citylife.geotools.demo;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.util.Map;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.table.DefaultTableModel;
import org.geotools.data.DataStore;
import org.geotools.data.DataStoreFactorySpi;
import org.geotools.data.DataStoreFinder;
import org.geotools.data.Query;
import org.geotools.data.postgis.PostgisNGDataStoreFactory;
import org.geotools.data.shapefile.ShapefileDataStoreFactory;
import org.geotools.data.simple.SimpleFeatureCollection;
import org.geotools.data.simple.SimpleFeatureIterator;
import org.geotools.data.simple.SimpleFeatureSource;
import org.geotools.filter.text.cql2.CQL;
import org.geotools.swing.action.SafeAction;
import org.geotools.swing.data.JDataStoreWizard;
import org.geotools.swing.table.FeatureCollectionTableModel;
import org.geotools.swing.wizard.JWizard;
import org.locationtech.jts.geom.Coordinate;
import org.locationtech.jts.geom.Geometry;
import org.locationtech.jts.geom.Point;
import org.opengis.feature.simple.SimpleFeature;
import org.opengis.feature.type.FeatureType;
import org.opengis.filter.Filter;

public class Class4QueryLab extends JFrame {
  /**
   * 
   */
  private static final long serialVersionUID = 1L;

  private DataStore dataStore;

  private JComboBox<String> featureTypeCBox;

  private JTable table;

  private JTextField text;

  public static void main(String[] args) throws Exception {
    JFrame frame = new Class4QueryLab();
    frame.setVisible(true);
  }

  // 构造函数画面定义
  public Class4QueryLab() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    getContentPane().setLayout(new BorderLayout());

    text = new JTextField(80);
    text.setText("include"); // include selects everything!
    getContentPane().add(text, BorderLayout.NORTH);

    table = new JTable();
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    table.setModel(new DefaultTableModel(5, 5));
    table.setPreferredScrollableViewportSize(new Dimension(500, 200));

    JScrollPane scrollPane = new JScrollPane(table);
    getContentPane().add(scrollPane, BorderLayout.CENTER);

    JMenuBar menubar = new JMenuBar();
    setJMenuBar(menubar);

    JMenu fileMenu = new JMenu("File");
    menubar.add(fileMenu);

    featureTypeCBox = new JComboBox<>();
    menubar.add(featureTypeCBox);

    JMenu dataMenu = new JMenu("Data");
    menubar.add(dataMenu);
    pack();

    // 绑定文件、数据源选择事件
    fileMenu.add(new SafeAction("Open shapefile...") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        connect(new ShapefileDataStoreFactory());
      }
    });
    
    fileMenu.add(new SafeAction("Connect to PostGIS database...") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        connect(new PostgisNGDataStoreFactory());
      }
    });
    
    fileMenu.add(new SafeAction("Connect to DataStore...") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        connect(null);
      }
    });
    
    fileMenu.addSeparator();
    
    fileMenu.add(new SafeAction("Exit") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        System.exit(0);
      }
    });

    // 绑定数据处理事件
    dataMenu.add(new SafeAction("Get features") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        filterFeatures();
      }
    });
    
    dataMenu.add(new SafeAction("Count") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        countFeatures();
      }
    });
    
    dataMenu.add(new SafeAction("Geometry") {
      /**
       * 
       */
      private static final long serialVersionUID = 1L;

      public void action(ActionEvent e) throws Throwable {
        queryFeatures();
      }
    });
  }

  /**
   * 连接数据源
   * 
   * @param format
   * @throws Exception
   */
  private void connect(DataStoreFactorySpi format) throws Exception {
    JDataStoreWizard wizard = new JDataStoreWizard(format);
    int result = wizard.showModalDialog();
    if (result == JWizard.FINISH) {
      Map<String, Object> connectionParameters = wizard.getConnectionParameters();
      dataStore = DataStoreFinder.getDataStore(connectionParameters);
      if (dataStore == null) {
        JOptionPane.showMessageDialog(null, "Could not connect - check parameters");
      }
      updateUI();
    }
  }

  /**
   * 刷新UI
   * 
   * @throws Exception
   */
  private void updateUI() throws Exception {
    ComboBoxModel<String> cbm = new DefaultComboBoxModel<>(dataStore.getTypeNames());
    featureTypeCBox.setModel(cbm);

    table.setModel(new DefaultTableModel(5, 5));
  }

  /**
   * 查询数据
   * 
   * @throws Exception
   */
  private void filterFeatures() throws Exception {
    String typeName = (String) featureTypeCBox.getSelectedItem();
    SimpleFeatureSource source = dataStore.getFeatureSource(typeName);

    Filter filter = CQL.toFilter(text.getText());
    SimpleFeatureCollection features = source.getFeatures(filter);
    FeatureCollectionTableModel model = new FeatureCollectionTableModel(features);
    table.setModel(model);
  }

  /**
   * 计数数据
   * 
   * @throws Exception
   */
  private void countFeatures() throws Exception {
    String typeName = (String) featureTypeCBox.getSelectedItem();
    SimpleFeatureSource source = dataStore.getFeatureSource(typeName);

    Filter filter = CQL.toFilter(text.getText());
    SimpleFeatureCollection features = source.getFeatures(filter);

    int count = features.size();
    JOptionPane.showMessageDialog(text, "Number of selected features:" + count);
  }

  /**
   * 取得几何数据详情
   * 
   * @throws Exception
   */
  private void queryFeatures() throws Exception {
    String typeName = (String) featureTypeCBox.getSelectedItem();
    SimpleFeatureSource source = dataStore.getFeatureSource(typeName);

    FeatureType schema = source.getSchema();
    String name = schema.getGeometryDescriptor().getLocalName();

    Filter filter = CQL.toFilter(text.getText());

    Query query = new Query(typeName, filter, new String[] {name});

    SimpleFeatureCollection features = source.getFeatures(query);

    FeatureCollectionTableModel model = new FeatureCollectionTableModel(features);
    table.setModel(model);
  }

}
